/*
 * This file is part of TradeHelper library.
 *
 * TradeHelper library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * TradeHelper library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with TradeHelper library.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.rag.forum.ui;

import com.alee.extended.drag.ParentProxyDropHandler;
import com.alee.extended.drag.TextDragHandler;
import com.alee.extended.filechooser.WebFilePlate;
import com.alee.laf.StyleConstants;
import com.alee.laf.button.WebButton;
import com.alee.laf.label.WebLabel;
import com.alee.laf.panel.WebPanel;
import com.alee.utils.LafUtils;
import com.alee.utils.laf.FocusType;
import com.alee.utils.swing.AncestorAdapter;
import com.alee.utils.swing.Timer;
import com.rag.core.Item;
import com.rag.utils.RagUtils;
import info.clearthought.layout.TableLayout;

import javax.swing.*;
import javax.swing.event.AncestorEvent;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

/**
 * User: mgarin Date: 12.04.12 Time: 18:45
 */

public class ItemPlate extends WebPanel
{
    private List<ActionListener> closeListeners = new ArrayList<ActionListener> ();

    private boolean animate = false;

    private Item item;

    private Timer animator = null;
    private float opacity = 0f;

    private WebLabel fileName;
    private WebButton remove = null;

    public ItemPlate ( Item item )
    {
        this ( item, true );
    }

    public ItemPlate ( Item item, boolean decorated )
    {
        super ( decorated );
        initializeFilePlate ( item );
    }

    private void initializeFilePlate ( Item item )
    {
        this.item = item;

        // Для драга и дропа итемов
        final ParentProxyDropHandler ppdh = new ParentProxyDropHandler ( this );
        setTransferHandler ( new TextDragHandler ( this, item.getId () )
        {
            public boolean canImport ( TransferHandler.TransferSupport info )
            {
                return ppdh.canImport ( info );
            }

            public boolean importData ( TransferHandler.TransferSupport info )
            {
                return ppdh.importData ( info );
            }
        } );

        setFocusable ( true );

        TableLayout tableLayout = new TableLayout (
                new double[][]{ { TableLayout.FILL, TableLayout.PREFERRED },
                        { TableLayout.PREFERRED } } );
        tableLayout.setHGap ( 0 );
        tableLayout.setVGap ( 0 );
        setLayout ( tableLayout );

        // Лэйбл для имени и иконки итема
        fileName = new WebLabel ();
        fileName.setMargin ( 2 );
        add ( fileName, "0,0" );

        // Обновляем имя и иконку
        updateFileName ();

        // Добавляем кнопку удаления итема

        remove = WebButton.createIconWebButton ( WebFilePlate.CROSS_ICON );
        remove.setRound ( StyleConstants.smallRound );
        remove.setShadeWidth ( 3 );
        remove.setInnerShadeWidth ( 2 );
        remove.setRolloverDecoratedOnly ( true );
        remove.setFocusable ( false );
        remove.addActionListener ( new ActionListener ()
        {
            public void actionPerformed ( final ActionEvent ae )
            {
                startRemoval ( ae );
            }
        } );
        add ( remove, "1,0" );

        // Слушатель для удаления итема
        addMouseListener ( new MouseAdapter ()
        {
            public void mousePressed ( MouseEvent e )
            {
                if ( SwingUtilities.isLeftMouseButton ( e ) )
                {
                    ItemPlate.this.requestFocusInWindow ();
                }
                else if ( SwingUtilities.isMiddleMouseButton ( e ) )
                {
                    deleteItem ();
                }
            }
        } );

        // Слушатель для анимации появления итема
        addAncestorListener ( new AncestorAdapter ()
        {
            public void ancestorAdded ( AncestorEvent event )
            {
                if ( animator != null && animator.isRunning () )
                {
                    animator.stop ();
                }
                if ( animate )
                {
                    animator = new Timer ( 1000 / StyleConstants.animationFps, null );
                    animator.addActionListener ( new ActionListener ()
                    {
                        public void actionPerformed ( ActionEvent e )
                        {
                            opacity += 0.1f;
                            if ( opacity < 1f )
                            {
                                ItemPlate.this.repaint ();
                            }
                            else
                            {
                                opacity = 1f;
                                ItemPlate.this.repaint ();
                                animator.stop ();
                            }
                        }
                    } );
                    animator.start ();
                }
                else
                {
                    opacity = 1f;
                    ItemPlate.this.repaint ();
                }
            }
        } );

        // Слушатель фокуса для перерисовки
        addFocusListener ( new FocusAdapter ()
        {
            public void focusGained ( FocusEvent e )
            {
                repaint ();
            }

            public void focusLost ( FocusEvent e )
            {
                repaint ();
            }
        } );

        // Меню
        RagUtils.setupItemMenu ( this, null, item, true );
    }

    public Item getItem ()
    {
        return item;
    }

    public void deleteItem ()
    {
        startRemoval ( new ActionEvent ( ItemPlate.this, 0, "Item delete" ) );
    }

    private void updateFileName ()
    {
        fileName.setIcon ( item.getSmallIcon () );
        fileName.setText ( item.getText () );
    }

    private void startRemoval ( final ActionEvent ae )
    {
        if ( animator != null && animator.isRunning () )
        {
            animator.stop ();
        }
        if ( animate )
        {
            animator = new Timer ( 1000 / StyleConstants.animationFps, new ActionListener ()
            {
                public void actionPerformed ( ActionEvent e )
                {
                    opacity -= 0.1f;
                    if ( opacity > 0f )
                    {
                        ItemPlate.this.repaint ();
                    }
                    else
                    {
                        // Удаляем панель с итемом
                        removeFromParent ();

                        // Уведомляем об удалении
                        fireActionPerformed ( ae );

                        // Останавливаем анимацию
                        animator.stop ();
                    }
                }
            } );
            animator.start ();
        }
        else
        {
            // Удаляем панель с итемом
            removeFromParent ();
        }
    }

    private void removeFromParent ()
    {
        // Меняем видимость панели с итемом
        opacity = 0f;

        // Окончательно удаляем итем
        Container container = this.getParent ();
        if ( container != null && container instanceof ItemDropList )
        {
            ( ( ItemDropList ) container ).removeItem ( item );
        }
    }

    protected void paintComponent ( Graphics g )
    {
        Graphics2D g2d = ( Graphics2D ) g;
        Composite old = LafUtils.setupAlphaComposite ( g2d, opacity, opacity < 1f );

        super.paintComponent ( g );

        LafUtils.drawWebFocus ( g2d, this, FocusType.fieldFocus, getShadeWidth (), getRound () );
    }

    public void addCloseListener ( ActionListener actionListener )
    {
        closeListeners.add ( actionListener );
    }

    public void removeCloseListener ( ActionListener actionListener )
    {
        closeListeners.remove ( actionListener );
    }

    private void fireActionPerformed ( ActionEvent e )
    {
        List<ActionListener> listeners = new ArrayList<ActionListener> ();
        listeners.addAll ( closeListeners );
        for ( ActionListener listener : listeners )
        {
            listener.actionPerformed ( e );
        }
    }
}